@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion

:: 定义空格字符串用于填充
set "spaces=                          "

:: Get input parameters
set "MAP_PATH=%~1"
set "MAP_NAME=%~n1"
set "ROOT_DIR=%~2"

@REM echo [INFO] MAP_PATH: %MAP_PATH%
@REM echo [INFO] MAP_NAME: %MAP_NAME%
@REM echo [INFO] ROOT_DIR: %ROOT_DIR%

:: Locate .map file
:: Try locating .map file in Listings first
set "MAP_FILE=%MAP_PATH%.map"

if exist "!MAP_FILE!" (
    echo [INFO] MAP file found in Listings: !MAP_FILE!
) else (
    :: Fallback to Objects directory
    set "MAP_FILE=%ROOT_DIR%Listings\%MAP_NAME%.map"
    if exist "!MAP_FILE!" (
        echo [INFO] MAP file found in Objects: !MAP_FILE!
    ) else (
        echo [ERROR] MAP file not found in Listings or Objects.
        exit /b 1
    )
)

:: Locate .sct file in Objects directory
set "SCT_FILE=%MAP_PATH%.sct"

if not exist "!SCT_FILE!" (
    echo [WARN] Scatter file not found: !SCT_FILE!
    echo [INFO] Using default memory size: ROM=32768, RAM=8192
    set TOTAL_ROM=32768
    set TOTAL_RAM=8192
) else (
    echo [INFO] Parsing scatter file: !SCT_FILE!

    :: Extract ROM size
    for /f "tokens=3" %%a in ('findstr /c:"LR_IROM1" "!SCT_FILE!"') do (
        set "ROM_HEX=%%a"
        if not "%%a"=="" (
            call set /a TOTAL_ROM=%%a
        )
    )

    :: Extract RAM size
    for /f "tokens=3" %%a in ('findstr /c:"RW_IRAM1" "!SCT_FILE!"') do (
        set "RAM_HEX=%%a"
        if not "%%a"=="" (
            call set /a TOTAL_RAM=%%a
        )
    )
    echo [INFO] ROM_HEX=!ROM_HEX! [!TOTAL_ROM! bytes]
    echo [INFO] RAM_HEX=!RAM_HEX! [!TOTAL_RAM! bytes]
)

:: 查找 .s 文件
for /r %%f in (*.s) do (
    set "SFILE=%%f"
    goto :found_s
)
echo [WARN] No .s file found.

:found_s
echo [INFO] Found startup file: !SFILE!

:: 提取 Stack_Size
for /f "tokens=1,2,3" %%a in ('findstr /r /c:"^Stack_Size[ ]*EQU" "!SFILE!"') do (
    set "STACK_HEX=%%c"
    if not "%%c"=="" (
        call set /a STACK_SIZE=%%c
    )
)

:: 提取 Heap_Size
for /f "tokens=1,2,3" %%a in ('findstr /r /c:"^Heap_Size[ ]*EQU" "!SFILE!"') do (
    set "HEAP_HEX=%%c"
    if not "%%c"=="" (
        call set /a HEAP_SIZE=%%c
    )
)

:: 打印结果
echo [INFO] STACK_HEX=!STACK_HEX! [!STACK_SIZE! bytes]
echo [INFO] HEAP_HEX=!HEAP_HEX! [!HEAP_SIZE! bytes]

set "HTM_FILE=%MAP_PATH%.htm"
if exist "!HTM_FILE!" (
    @REM echo [INFO] HTM file found: !HTM_FILE!
    for /f "tokens=*" %%l in ('findstr /c:"Maximum Stack Usage" "%HTM_FILE%"') do (
        echo [STACK] %%l
        goto :next
    )
)

) else (
    echo [WARN] HTM file not found: !HTM_FILE!
)
:next
:: Extract sizes from .map file
for /f "tokens=8" %%x in ('findstr /c:"Total RO  Size" "!MAP_FILE!"') do set "total_ro=%%x"
for /f "tokens=9" %%x in ('findstr /c:"Total RW  Size" "!MAP_FILE!"') do set "total_rw=%%x"
for /f "tokens=11" %%x in ('findstr /c:"Total ROM Size" "!MAP_FILE!"') do set "used_rom=%%x"

@REM echo [DEBUG] Extracted RO size: !total_ro!
@REM echo [DEBUG] Extracted RW size: !total_rw!
@REM echo [DEBUG] Extracted ROM size: !used_rom!

:: Convert to KB and calculate usage percentage
call :toKB !total_ro! total_ro_kb
call :toKB !total_rw! total_rw_kb
call :toKB !used_rom! total_rom_kb

call :percent %total_ro% %TOTAL_ROM% ro_percent
call :percent %total_rw% %TOTAL_RAM% rw_percent
call :percent %used_rom% %TOTAL_ROM% rom_percent

:: 定义空格字符串（用于对齐）
set "spaces=                                "
:: ===================== 表头 =====================
:: 设置表头字段
set "input=Type" & set "width=12" & call :padRightSafe head_type
set "input=Size" & set "width=6" & call :padRightSafe head_size
set "input=[KB]" & set "width=9" & call :padRightSafe head_kb
set "input=##########__________ | Usage%%" & set "width=29" & call :padRightSafe head_usage
set "input=Total" & set "width=6" & call :padRightSafe head_total

:: 输出表头
echo ==============================================================================
echo                            Memory Usage Summary
echo ==============================================================================
echo ^| !head_type! ^| !head_size! ^| !head_kb! ^| !head_usage! ^| !head_total! ^|
echo ------------------------------------------------------------------------------

:: ===================== RO 行 =====================
set "input=RO (Code+RO)" & set "width=12" & call :padRightSafe type_ro
set "input=!total_ro!" & set "width=6" & call :padRightSafe size_ro
set "input=[!total_ro_kb! KB]" & set "width=9" & call :padRightSafe kb_ro
set "input=!ro_percent!%%" & set "width=8" & call :padRightSafe usage_ro
call :ShowProgressText !ro_percent! bar_ro
set "input=!bar_ro! !usage_ro!" & set "width=29" & call :padRightSafe usage_robar
set "input=%TOTAL_ROM%" & set "width=6" & call :padRightSafe total_ro
echo ^| !type_ro! ^| !size_ro! ^| !kb_ro! ^| !usage_robar! ^| !total_ro! ^|

:: ===================== RW 行 =====================
set "input=RW (RW+ZI)" & set "width=12" & call :padRightSafe type_rw
set "input=!total_rw!" & set "width=6" & call :padRightSafe size_rw
set "input=[!total_rw_kb! KB]" & set "width=9" & call :padRightSafe kb_rw
set "input=!rw_percent!%%" & set "width=12" & call :padRightSafe usage_rw
call :ShowProgressText !rw_percent! bar_rw
set "input=!bar_rw! !usage_rw!" & set "width=29" & call :padRightSafe usage_rwbar
set "input=%TOTAL_RAM%" & set "width=6" & call :padRightSafe total_rw
echo ^| !type_rw! ^| !size_rw! ^| !kb_rw! ^| !usage_rwbar! ^| !total_rw! ^|

:: ===================== ROM Used 行 =====================
set "input=ROM Used" & set "width=12" & call :padRightSafe type_rom
set "input=!used_rom!" & set "width=6" & call :padRightSafe size_rom
set "input=[!total_rom_kb! KB]" & set "width=9" & call :padRightSafe kb_rom
set "input=!rom_percent!%%" & set "width=12" & call :padRightSafe usage_rom
call :ShowProgressText !rom_percent! bar_rom
set "input=!bar_rom! !usage_rom!" & set "width=29" & call :padRightSafe usage_rombar
set "input=%TOTAL_ROM%" & set "width=6" & call :padRightSafe total_rom
echo ^| !type_rom! ^| !size_rom! ^| !kb_rom! ^| !usage_rombar! ^| !total_rom! ^|

echo ==============================================================================

endlocal
exit /b 0

:: Convert bytes to KB (2 decimal places, rounded)
:toKB
setlocal enabledelayedexpansion
set "bytes=%~1"
set "varname=%~2"
set /a "kb=(bytes*200 + 1024)/2048"
set /a whole=kb/100
set /a frac=kb%%100
if !frac! lss 10 (
    set "result=!whole!.0!frac!"
) else (
    set "result=!whole!.!frac!"
)
endlocal & set "%varname%=%result%"
exit /b

:: Calculate percentage (2 decimal places, rounded)
:percent
setlocal enabledelayedexpansion
set "val1=%~1"
set "val2=%~2"
set "varname=%~3"
@REM echo [DEBUG] :percent val1=!val1!, val2=!val2!
set /a "result=(10000*val1 + val2/2)/val2"
set /a whole=result/100
set /a frac=result%%100
if !frac! lss 10 (
    set "result=!whole!.0!frac!"
) else (
    set "result=!whole!.!frac!"
)
endlocal & set "%varname%=%result%"
exit /b

:: Pad a string to the right with spaces
:padRight
:: %1 = input string, %2 = total width, %3 = output variable name
setlocal enabledelayedexpansion
set "str=%~1"
set "width=%~2"
set "varname=%~3"
set "padded=!str!!spaces!"
set "padded=!padded:~0,%width%!"
endlocal & set "%varname%=%padded%"
exit /b

:: ===================== padRightSafe Subroutine =====================
:: Pads a string with spaces to the right up to a fixed width
:: Input:  input, width
:: Output: %1 (e.g. result variable name)
:padRightSafe
setlocal enabledelayedexpansion
set "padded=!input!!spaces!"
set "padded=!padded:~0,%width%!"
endlocal & set "%~1=%padded%"
goto :eof

:ShowProgressText
setlocal enabledelayedexpansion
set "barlen=20"
set "percent=%~1"
for /f "delims=." %%a in ("%percent%") do set /a filled=%%a * barlen / 100
set "bar="
for /l %%i in (1,1,!barlen!) do (
    if %%i leq !filled! (
        set "bar=!bar!#"
    ) else (
        set "bar=!bar!_"
    )
)
endlocal & set "%~2=%bar% |"
goto :eof


